﻿using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Web.DynamicData;
using System.Web.Routing;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.Expressions;
using NotAClue.ComponentModel.DataAnnotations;
using NotAClue.Web.DynamicData;
using NotAClue.Web;
using NotAClue;

namespace DD_Extensions
{
    public partial class UpdateableList : System.Web.UI.Page
    {
        protected MetaTable table;
        protected ListViewAttribute _listViewAttribute;

        protected void Page_Init(object sender, EventArgs e)
        {
            //?Canceled=True
            var canceled = Request.QueryString["Canceled"] != null;

            table = DynamicDataRouteHandler.GetRequestMetaTable(Context);
            if (canceled)
            {
                var defaultValues = Page.GetFilterValuesFromSession(table, table.GetColumnValuesFromRoute(Context));
                ListView1.SetMetaTable(table, defaultValues);
            }
            else
                ListView1.SetMetaTable(table, table.GetColumnValuesFromRoute(Context));
            
            GridDataSource.EntityTypeFilter = table.EntityType.Name;

            // set initial sort order
            GridQueryExtender.SetInitialSortOrder(table);

            // setup the multicolumn text search
            if (GridQueryExtender.SetupMultiColumnTextSearch(table, GridDataSource, Context, txbMultiColumnSearch))
            {
                MultiSearch.Visible = true;

                // get filter value
                var searchText = Page.GetFilterValueFromSession(table, table.Name + Global.MULTI_COLUMN_SEARCH);
                if (canceled && searchText != null)
                    txbMultiColumnSearch.Text = searchText.ToString();
            }

            //ListView1.PageSize = table.GetAttributeOrDefault<TableOptionsAttribute>().RowsPerPage;

            //// set pager from session
            //var pagerPage = Page.GetFilterValueFromSession(table, table.Name + Global.CURRENT_PAGER_PAGE);
            //if (canceled && pagerPage != null)
            //    ListView1.PageIndex = (int)pagerPage;

            //// make search text box be remembered 
            //// for browser back button
            //Page.DisablePartialRenderingForUpload(table);

            //// setup export
            //var export = table.GetAttribute<ExportAttribute>();
            //if (export != null && export.Export == true)
            //{
            //    ExportSpan.Visible = true;
            //    if (export.AllowShowAllColumns)
            //        ShowAllColumnsCheckbox.Visible = true;
            //}

            _listViewAttribute = table.GetAttributeOrDefault<ListViewAttribute>();
            if (_listViewAttribute == null)
                return;

            // enable update, delete and insert
            GridDataSource.EnableDelete = _listViewAttribute.EnableDelete;
            GridDataSource.EnableInsert = _listViewAttribute.EnableInsert;
            GridDataSource.EnableUpdate = _listViewAttribute.EnableUpdate;

            CommandButtons enabledButtons = CommandButtons.NoButtons;
            enabledButtons = _listViewAttribute.EnableDelete ? CommandButtons.Delete : CommandButtons.NoButtons;
            enabledButtons = _listViewAttribute.EnableDetails ? (enabledButtons | CommandButtons.Details) : enabledButtons;
            enabledButtons = _listViewAttribute.EnableUpdate ? (enabledButtons | CommandButtons.Edit) : enabledButtons;
            enabledButtons = _listViewAttribute.EnableInsert ? (enabledButtons | CommandButtons.Insert) : enabledButtons;
            enabledButtons = _listViewAttribute.EnableRefresh ? (enabledButtons | CommandButtons.Refresh) : enabledButtons;

            // add dynamic validator for each mode allowed on table
            var modes = EnumWebExtensionMethods.GetEnumList(typeof(ListViewTemplateMode));
            foreach (ListItem item in modes)
            {
                var validationGroup = String.Format("{0}_{1}", table.Name, item.Text);
                var validationSummary = new ValidationSummary()
                {
                    ValidationGroup = validationGroup,
                    CssClass = "DDValidator",
                    EnableClientScript = true,
                    HeaderText = "List of validation errors"
                };
                PlaceHolder1.Controls.Add(validationSummary);

                var dynamicValidator = new DynamicValidator()
                {
                    ControlToValidate = "ListView1",
                    ValidationGroup = validationGroup,
                    CssClass = "DDValidator",
                    Display = ValidatorDisplay.None,
                    Text = "*"
                };
                PlaceHolder1.Controls.Add(dynamicValidator);
            }

            var hideColumns = new String[0];
            ListView1.GetTemplates(table, 
                enabledButtons, 
                table.Name, 
                "DDGridView",
                hideColumns,
                false,
                commandCellPosition: CommandCellPosition.Left,
                wrapOn: false);

            // set the data key names
            ListView1.DataKeyNames = table.GetDataKeysNames();

            // hide insert row
            ListView1.InsertItemPosition = InsertItemPosition.None;
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            Title = table.DisplayName;
            GridDataSource.Include = table.ForeignKeyColumnsNames;

            // Disable various options if the table is readonly
            if (table.IsReadOnly)
                ListView1.EnablePersistedSelection = false;

            if (FilterRepeater.Controls.Count == 0 && !MultiSearch.Visible)
                Filters.Visible = false;

            if (FilterRepeater.Controls.Count == 0)
                ClearFiltersDiv.Visible = false;
        }

        protected void Label_PreRender(object sender, EventArgs e)
        {
            Label label = (Label)sender;
            DynamicFilter dynamicFilter = (DynamicFilter)label.FindControl("DynamicFilter");
            QueryableFilterUserControl filter = dynamicFilter.FilterTemplate as QueryableFilterUserControl;
            if (filter != null && filter.FilterControl != null)
                label.AssociatedControlID = filter.FilterControl.GetUniqueIDRelativeTo(label);
        }

        //protected void Filter(object sender, CustomExpressionEventArgs e)
        //{
        //}

        protected void DynamicFilter_FilterChanged(object sender, EventArgs e)
        {
            //ListView1.PageIndex = 0;
        }

        protected void ListView1_ItemDataBound(object sender, ListViewItemEventArgs e)
        {
            //if (e.Item.ItemType == ListViewItemType.DataItem && _listViewAttribute.DisableInLineEdit)
            //{
            //    var entity = e.Item.DataItem.GetEntity();
            //    var url = table.GetActionPath(PageAction.Edit, entity);
            //    var editButton = e.Item.FindIButtonControlRecursive("Edit");
            //    if (editButton != null)
            //        editButton.PostBackUrl = url;
            //}
        }

        protected void ListView1_ItemCommand(object sender, ListViewCommandEventArgs e)
        {
            // show insert row
            if (e.CommandName == "ShowInsert")
                ListView1.InsertItemPosition = InsertItemPosition.FirstItem;

            // do refresh
            if (e.CommandName == "Refresh")
                ListView1.DataBind();

            // hide insert row
            if (e.CommandName == "Cancel")
                ListView1.InsertItemPosition = InsertItemPosition.None;

            //if (e.CommandName == "Edit" && !_showChildren.EnableInLineEdit)
            //    Response.Redirect(table.GetActionPath(PageAction.Edit, e.Item));
        }

        protected void ListView1_ItemInserted(object sender, ListViewInsertedEventArgs e)
        {
            // hide insert row
            ListView1.InsertItemPosition = InsertItemPosition.None;
        }

        protected void ClearFiltersButton_Click(object sender, EventArgs e)
        {
            Page.ClearTableFilters(table);
            Response.Redirect(table.ListActionPath);
        }

        protected void btnMultiColumnSearch_Click(object sender, EventArgs e)
        {
            var button = (Button)sender;
            if (button.ID == btnMultiColumnSearchClear.ID)
                txbMultiColumnSearch.Text = String.Empty;

            Page.AddCustomFilterValueToSession(table, table.Name + Global.MULTI_COLUMN_SEARCH, txbMultiColumnSearch.Text);
        }

        //protected void btnExport_Click(object sender, EventArgs e)
        //{
        //    if (GridView1 != null)
        //        GridView1.Export(showAllColumns: ShowAllColumnsCheckbox.Checked);
        //}

        /// <summary>
        /// Fixes the sort by column issue with EF
        /// see http://forums.asp.net/p/1528965/3811692.aspx#3811692
        /// </summary>
        protected void GridDataSource_Selecting(object sender, EntityDataSourceSelectingEventArgs e)
        {
            string s = e.SelectArguments.SortExpression;
            if (s.StartsWith("it."))
                e.SelectArguments.SortExpression = s.Substring(3);
        }

        protected void GridDataSource_Updating(object sender, EntityDataSourceChangingEventArgs e)
        {
            var a = e.Entity;
        }
    }
}